/*
 * Copyright 2015 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.samples.apps.iosched.schedule;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.CoreMatchers.is;

import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;

import com.google.samples.apps.iosched.lib.R;
import com.google.samples.apps.iosched.settings.SettingsUtils;
import com.google.samples.apps.iosched.util.TimeUtils;

import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;

/**
 * UI tests for {@link ScheduleActivity} interacting with other activities (adding/removing
 * session from schedule), when the user is attending the conference and the conference starts in 3
 * hours.
 * <p/>
 * This should be run on devices with a narrow layout only (phones all orientation, tablets in
 * portrait mode)
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class ScheduleActivity_InteractionsTest {

    @Rule
    public ActivityTestRule<ScheduleActivity> mActivityRule = new ActivityTestRule<>(
            ScheduleActivity.class);

    @Before
    public void setStartTimeAndDisableReminders() {
        // Set up time to 3 hours before conference
        TimeUtils.setCurrentTimeRelativeToStartOfConference(
                InstrumentationRegistry.getTargetContext(), TimeUtils.HOUR * 3);

        // Don't show notifications for sessions as they get in the way of the UI
        SettingsUtils.setShowNotifications(InstrumentationRegistry.getTargetContext(), false);
    }

    /**
     * This will fail if there is no free slot with available sessions. Due to the fact it interacts
     * with other screens that manipulate the schedule, it cannot be written with the {@link
     * StubScheduleModel}, as this model always returns the same schedule items.
     */
//    @Test
//    @Suppress // Test isn't deterministic when run as part of the full test suite.
//    public void addEventToMySchedule_Flaky() {
//        // Given a free slot with available sessions
//        findFreeSlotWithAvailableSessions();
//
//        // When adding the first available session
//        String title = addFirstAvailableSession();
//
//        // Then the session is shown
//        onView(withText(title)).check(matches(isDisplayed()));
//
//        // Clean up
//        removeSessionFromSchedule(title);
//    }

    /**
     * This will fail if there is no free slot with available sessions. Due to the fact it interacts
     * with other screens that manipulate the schedule, it cannot be written with the {@link
     * StubScheduleModel}, as this model always returns the same schedule items.
     */
//    @Test
//    @Suppress // Test isn't deterministic when run as part of the full test suite.
//    public void removeEventToMySchedule_Flaky() {
//        // Given a session in the schedule
//        findFreeSlotWithAvailableSessions();
//        String title = addFirstAvailableSession();
//        onView(withText(title)).check(matches(isDisplayed()));
//
//        // When the session is removed
//        removeSessionFromSchedule(title);
//
//        // Then the session is not shown anymore
//        onView(withText(title)).check(matches(not(isDisplayed())));
//    }

    /**
     * This finds the first free slow with available session and click on "Browse sessions" so the
     * list of available sessions is now displayed
     */
//    private void findFreeSlotWithAvailableSessions() {
//        TypedArray ids = InstrumentationRegistry.getTargetContext().getResources()
//                .obtainTypedArray(R.array.myschedule_listview_ids);
//        //noinspection ResourceType
//        int listViewId = ids.getResourceId(1, 0);
//        ids.recycle();
//        onData(allOf(is(instanceOf(ScheduleItem.class)),
//                new FirstFreeSlotWithAvailableSessionsMatcher()))
//                .inAdapterView(withId(listViewId)).onChildView(withId(R.id.browse_sessions))
//                .perform(click());
//    }

//    DISABLED: Broken
//    /**
//     * This assumes that the screen shows a list of available sessions. It adds the first one to the
//     * schedule then goes back to the schedule screen.
//     *
//     * @return the title of the session that was added
//     */
//    private String addFirstAvailableSession() {
//        onData(is(instanceOf(Integer.class))).inAdapterView(withId(R.id.sessions_list))
//                                             .atPosition(0).perform(click());
//
//        // Session details screen
//        String title = MatchersHelper.getText(withId(R.id.session_title));
//        onView(withId(R.id.add_schedule_button)).perform(click());
//
//        onView(withContentDescription(InstrumentationRegistry.getTargetContext()
//                                                             .getString(
//                                                                     R.string.close_and_go_back)))
//                .perform(click());
//        onView(withContentDescription(InstrumentationRegistry.getTargetContext()
//                                                             .getString(
//                                                                     R.string.close_and_go_back)))
//                .perform(click());
//
//        return title;
//    }
//
    private void removeSessionFromSchedule(String sessionTitle) {
        onView(withText(sessionTitle)).perform(click());
        onView(withId(R.id.add_schedule_button)).perform(click());
        onView(withContentDescription(InstrumentationRegistry.getTargetContext()
                                                             .getString(
                                                                     R.string.close_and_go_back)))
                .perform(click());
    }

}
